package com.atguigu.zy.interview.jvm.oom;

/**
 * @Author : Jungle
 * @Description :
 * 配置参数：
 * -Xms10m -Xmx10m -XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
 * <p>
 * 故障现象:
 * Exception in thread "main" java.Lang.OutOfMemoryError: Direct buffer memory
 * <p>
 * 导致原因:
 * 写NIO程序经常使用ByteBuffer来读取或者写入数据，这是一种基于通道(Channel)与缓冲区(Buffer)的I/0方式，
 * 它可以使用Native函数库直接分配堆外内存，然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。
 * 这样能在一些场景中显著提高性能，因为避兔了在java堆和Native堆中来回复制数据。
 * ByteBuffer.aLlocate(capability)第一种方式是分能JVA堆内存，属于GC管辖范围，由于露要拷贝所以速度相对较慢
 * ByteBuffer.allocteDirect(capability)第二种方式是分配oS本地内存，不属于GC管辖范围,,但是java堆中DirectByteBuffer是可以回收的，回收完会释放堆外内存
 * 由于不需要内存烤贝所以速度相对较快。
 * 但如果不断分配本地内存，堆内存很少使用，那么JVM就不露要执行GC，DirectByteBuffer对象们就不会被回收，
 * 这时候堆内存充足，但本地内存可能已经使用光了，再次尝试分配本地内存就会出现Qut0fWemoryError，那程序就直接崩溃了。
 */
//public class DirectBufferMemoryDemo {
//    public static void main(String[] args) {
//        System.out.println("配置的maxDirectMemory" + (sun.misc.VM.maxDirectMemory() / (double) 1024 / 1024) + "MB");
//
//        //@formatter:off  线程暂停一会儿
//        try { TimeUnit.SECONDS.sleep( 3 ); } catch (InterruptedException e) { e.printStackTrace();}
//        //@formatter:on
//        //我们配置5M实际创建对象6M ,堆外内存
//        ByteBuffer bb = ByteBuffer.allocateDirect(6 * 1024 * 1024);
//    }
//}
